通过Java批量导出带有图片的Excel文件数据 您所在的位置:网站首页 java excel截图 通过Java批量导出带有图片的Excel文件数据

通过Java批量导出带有图片的Excel文件数据

2024-07-11 15:44| 来源: 网络整理| 查看: 265

批量导出带有图片的Excel文件 一、思路解析二、关键源码三、总结

Java通过POI或者一些常见的Excel工具类能够轻易导出后台的结构化数据,但是最近面临一个新需求,需要将对应记录数据和图片网络地址在同一行中导出。

一、思路解析

Excel

一般我们看到的Excel表格是这样的。 首先,我们考虑需要使用List存放每一行的值,并且规定第一行即为表头,从第二行开始是数据。 伪代码是这样的:

List rowList = new ArrayList(); // Excel表头 rowList.add(Arrays.asList("序号","标题", "图片")); for(int i=0;i /** * Excel导出设置Workbook * @param title 导出Excel文件名称 * @param rowList 第一个List为表头,其余行为表数据 * @param downLoadPic 是否下载图片 * @throws IOException */ public static HSSFWorkbook warpSingleWorkbook(String title,List rowList, Boolean downLoadPic) throws IOException { if (rowList == null || rowList.isEmpty()) { throw new NullPointerException("the row list is null"); } HSSFWorkbook book = new HSSFWorkbook(); // 创建表 HSSFSheet sheet = book.createSheet(title); // 设置单元格默认宽度为20个字符 sheet.setDefaultColumnWidth(20); HSSFPatriarch patriarch = sheet.createDrawingPatriarch(); // 设置表头样式 HSSFCellStyle style = book.createCellStyle(); // 设置居左 style.setAlignment(HSSFCellStyle.ALIGN_LEFT); // 检测表头数据(表头不允许数据为空) List head = rowList.get(0); // 写数据 int size = rowList.get(0).size(); // 第几行 for (int i = 0; i book.close(); throw new NullPointerException("the "+(i+1)+"th row is null"); } if (size != row.size()) { book.close(); throw new IllegalArgumentException("the cell number of "+(i+1)+"th row is different form the first"); } HSSFRow sr = sheet.createRow(i); // 第几列 for (int j = 0; j if(StringUtils.isNotBlank(row.get(2).toString())){ sr.setHeight((short) (1800)); List images = Arrays.asList(row.get(14).toString().split(",")); int temp = j; for(String image : images){ // 调用封装好的下载图片方法 drawPictureInfoExcel(book, patriarch, i, j, image); j++; } } } else { setExcelValue(sr.createCell(j), row.get(j), style); } } } return book; } /** * 设置Excel浮点数可做金额等数据统计 * @param cell 单元格类 * @param value 传入的值 */ public static void setExcelValue(HSSFCell cell, Object value, HSSFCellStyle style){ // 写数据 if (value == null) { cell.setCellValue(""); }else { if (value instanceof Integer || value instanceof Long) { cell.setCellType(Cell.CELL_TYPE_NUMERIC); cell.setCellValue(Long.valueOf(value.toString())); } else if (value instanceof BigDecimal) { cell.setCellType(Cell.CELL_TYPE_NUMERIC); cell.setCellValue(((BigDecimal)value).setScale(3, RoundingMode.HALF_UP).doubleValue()); } else { cell.setCellValue(value.toString()); } cell.setCellStyle(style); } } /** * * @param wb * @param patriarch * @param rowIndex * @param columnIndex * @param pictureUrl */ private static void drawPictureInfoExcel(HSSFWorkbook wb,HSSFPatriarch patriarch,int rowIndex, int columnIndex,String pictureUrl){ //rowIndex代表当前行 try { URL url = new URL(pictureUrl); //打开链接 HttpURLConnection conn = (HttpURLConnection)url.openConnection(); //设置请求方式为"GET" conn.setRequestMethod("GET"); //超时响应时间为5秒 conn.setConnectTimeout(5 * 1000); //通过输入流获取图片数据 InputStream inStream = conn.getInputStream(); //得到图片的二进制数据,以二进制封装得到数据,具有通用性 byte[] data = readInputStream(inStream); //anchor主要用于设置图片的属性 // dx1:起始单元格的x偏移量, // dy1:起始单元格的y偏移量, // dx2:终止单元格的x偏移量, // dy2:终止单元格的y偏移量, // col1:起始单元格列序号,从0开始计算; // row1:起始单元格行序号,从0开始计算, // col2:终止单元格列序号,从0开始计算; // row2:终止单元格行序号,从0开始计算, HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 1023, 250,(short) columnIndex, rowIndex, (short) columnIndex, rowIndex); //Sets the anchor type (图片在单元格的位置) //0 = Move and size with Cells, 2 = Move but don't size with cells, 3 = Don't move or size with cells. anchor.setAnchorType(ClientAnchor.AnchorType.DONT_MOVE_AND_RESIZE); patriarch.createPicture(anchor, wb.addPicture(data, HSSFWorkbook.PICTURE_TYPE_PNG)); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } private static byte[] readInputStream(InputStream inStream) throws Exception{ ByteArrayOutputStream outStream = new ByteArrayOutputStream(); //创建一个Buffer字符串 byte[] buffer = new byte[1024]; //每次读取的字符串长度,如果为-1,代表全部读取完毕 int len = 0; //使用一个输入流从buffer里把数据读取出来 while( (len=inStream.read(buffer)) != -1 ){ //用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度 outStream.write(buffer, 0, len); } //关闭输入流 inStream.close(); //把outStream里的数据写入内存 return outStream.toByteArray(); } }

调用规则,从主入口进入方法,这里我们用下载蜡笔小新图片到Excel里为例,找到一张网络URL图片地址为:https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1595325136781&di=2f03af92dfac5476b81ad22f426e76ad&imgtype=0&src=http%3A%2F%2Fcdn.duitang.com%2Fuploads%2Fitem%2F201406%2F15%2F20140615002128_eWXnf.jpeg

@ApiOperation(value = "带图片报表导出", notes = "带图片报表导出", httpMethod = "GET") @RequestMapping(value = "/importReport", method = RequestMethod.GET) public void importReport(HttpServletRequest req, HttpServletResponse res) { List rowList = new ArrayList(); // Excel表头 rowList.add(Arrays.asList("序号","标题", "图片")); for(int i=0;i HSSFWorkbook wb = ExcelUtils.warpSingleWorkbook("带图片报表", rowList, true); res.reset(); res.setHeader("Content-type","application/octet-stream"); res.setContentType("application/octet-stream"); res.setContentType("application/vnd.ms-excel"); res.setHeader("Accept-Ranges", "bytes"); String fileName = "带图片报表" + "_" + CalendarUtils.doFormatString(new Date(), CalendarUtils.YYYYMMDDHHmmss) + ".xls"; fileName = new String(fileName.getBytes(), CommConstants.CHAESET_ZH); res.setHeader("Content-Disposition", "attachment;filename=" + fileName); // 文件流输出到rs里 wb.write(res.getOutputStream()); res.getOutputStream().flush(); res.getOutputStream().close(); wb.close(); } catch (IOException e) { e.printStackTrace(); } }

在网页端调用该方法后,导出的报表结果如下所示: result

三、总结

唯一需要注意的是导出网络图片到Excel需要解析网络图片,且需要设置导出图片的单元格位置,在理清楚需求之后网上有许多已经造好的轮子可以复用。而时间充裕的话,建议大家可以去研究一下文中ExcelUtils工具类中的源码。

参考资料:

POI 导出excel 包含图片导出将图片导出到excel表格中


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有